#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{

    ////我们对进程从定向 ./mefile > log.txt 结果变成调用两次 fwrite printf 调用一次write
    ////原因:
    ////printf fwrite库函数自带缓冲区当我们重定向到文件之后，变成了全缓冲
    ////而我们放在缓冲区的数据就不会立即刷新
    ////而当我们进程退出，会统一刷新写入文件当中
    ////但是fork之后父子数据发生写时拷贝，当父进程准备刷新的时候子进程也有同样一份数据则产生两份数据
    //write没有变化，说明没有缓冲区

    char* str1 = "printf fwrite\n";
    char* str2 = "printf printf\n";
    char* str3 = "printf write\n";

    fwrite(str1,strlen(str1),1,stdout);
    printf("%s",str2);

    write(1,str3,strlen(str3));
    
    fork();




    //我们将1号描述符重定向到磁盘件后，缓冲区的刷新方式成为了全缓冲。我们写的内容
    //并没有填满整个缓冲区，导致并不会将缓冲区的内容刷新到磁盘文件中
    //加fflush之后就可以触发刷新
    //close(1);
   // close(2);
   // int p = open("log.txt",O_RDWR | O_TRUNC);
   // if(p < 0)
   // {
   //     perror("open");
   //     return 1;
   // }

   // printf("hello 1%d\n",p);
   // fflush(stdout);

//    perror("hello perror");//通过这个代码可以验证出stderr是不带缓冲区的(由于stderr不带缓冲器所以可以直接把值重定向到文件里面)
    //close(p);






    //dup2可以将一个已有的文件描述符复制到另一个指定的文件描述符上。
    //通过读取0（stdin）的出入，将读取到的输入值存放到buff例在打印出来
   // int p = open("log.txt",O_RDWR | O_TRUNC);
   // if(p < 0)
   // {
   //     perror("open");
   //     return 1;
   // }
   // char buff[1024];
   // //close(1);

   // while(1)
   // {
   //     dup2(p,1);
   //     
   //     int r = read(0,buff,sizeof(buff)-1);
   //     if(r > 0)
   //     {
   //         printf("%s",buff);
   //         fflush(stdout);
   //     }
   //     else if(r = 0)
   //         break;
   //     else 
   //         exit(1);

   // }

    //重定向
    //1号文件是输出，当我们把一号文件关闭，在把一号文件设为lot.txt
    //那么。本应该输出到显示器的内容这时候就输出到了log.txt文件上
  //  close(1); //关闭stdout
  //  int p = open("log.txt",O_RDWR | O_TRUNC);
  //  if(p < 0)
  //  {
  //      perror("open");
  //      return 1;
  //  }

  //  printf("%d\n",p);
  //  fflush(stdout);
  //  close(p);
    
    //如果把0（stdin），那么在pcb文件管理表中找到当前没有被使用的最小的一个下标·作为新的文件描述符
//    close(0);
//
//    int p = open("log.txt",O_RDONLY);
//    if(p < 0)
//    {
//        perror("open");
//        return 1;
//    }
//    printf("%d\n",p);
//

/************* 输入输出 ****************
    char buff[1024];
    int s = read(0,buff,sizeof(buff));
    if(s > 0)
    {
        buff[s];
        write(1,buff,strlen(buff));
    }
**********************************/

    /************** 以系统调用方式读 ***********************************8
    int p = open("log.txt",O_RDONLY);
    if(p < 0)
    {
        perror("open");
        return 1;
    }
    
    char buff[1024];
    char* log = "hello wzh\n";
    while(1)
    {
        int r = read(p,buff,strlen(log));
        if(r > 0)
        {
            printf("%s",buff);
        }
        //读取到文件末尾会返回0
        //若读取成功，read 函数会返回实际读取的字节数。
        //这个值可能小于 count，例如已经到达文件末尾，
        //或者读取设备时数据量不足。当到达文件末尾时，read 会返回 0。
        else
            break;
    }
    close(p);
******************************************************/

  

    /*************** 以系统调用方式写  *********************
    //int p = open("log.txt",O_WRONLY | O_TRUNC);   //写的方式打开，每次写都会把内容清空在写int p = open("log.txt",O_WRONLY | O_APPEND);   //写的方式打开，每次写都会把内容清空在写
    int p = open("log.txt",O_WRONLY | O_APPEND);   //写的方式打开，追加写
    if(p < 0)
    {
        perror("open");
        return 1;
    }
    const char* buff = "hello wzh\n";
    printf("%d\n",p);
    write(p,buff,strlen(buff));

    printf("成功写入\n");
    close(p);
****************************************/
    return 0;
}





























//int main(int argc,char* argv[])
//{
//    if(argc != 2)
//    {
//        printf("error\n");
//        return 1;
//    }
//    FILE* p = fopen(argv[1],"r");
//    if(p == NULL)
//    {
//        printf("fopen error\n");
//        return 2;
//    }
//    char buff[1024] = {0};
//
//    while(1)
//    {
//        int rread = fread(buff,1,sizeof(buff),p);  //每次读取一个字节，从buff数组里边读取102个
//       // int rread = fread(buff,sizeof(buff),1,p); //一次读取1024个字节，读取一次(错误做法)
//        if(rread > 0)
//        {
//            printf("%s",buff);
//            break;
//        }
//        
//        if(feof(p))
//            break;
//    }
//    fclose(p);
//
//    return 0;
//}
//

//int main()
//{

    /******************** 语言层面的读 ************************
    FILE* f = fopen("log.txt","r");
    if(f==NULL)
        perror("fopen");

    char out[] = "hello wzh\n";
    char rd[100] = {0};
    while(true)
    {
        //第2个参数与第2个参数的联系：
        //文件里面有四行hello wzh\n
        //当第2个参数为strlen(out),第三个·参数为1时获取到一行hello wzh\n
        //当第2个参数为1,第三个·参数为4时获取到 hell
        //
        int rread = fread(rd,strlen(out),4,f);
        if(rread > 0)
        {
            printf("%s",rd);
            break;
        }
    }
    fclose(f);
******************************************************/

    /************* 语言层面的写 ******************************
    FILE* f = fopen("log.txt","w");
    if(f==NULL)
        perror("fopen");

    char out[] = "hello wzh\n";
    int cnt = 5;
    while(cnt > 1)
    {
        fwrite(out,strlen(out),1,f);
        cnt--;
    }
    fclose(f);
    *******************************************/
  //  return 0;
//}
